//
//  Link.swift
//  Link
//
//  Created by melvyn on 2018/8/20.
//  Copyright © 2018 NEET. All rights reserved.
//

import Foundation
import Alamofire

func assertMainThread() {
    assert(Thread.isMainThread, "Link must be used only from the main thread. Use from background threads will lead to unexpected behavior and crashes.")
}

open class Link {
    
    public let sessionStore: SessionStore<AuthSession>
    
    public static let shared: Link = {
       let instance = Link.init()
        return instance
    }()
    
    public init() {
        sessionStore = SessionStore.init()
        sessionStore.userDidSaved = { auth in
            NotificationCenter.default.post(name: .userDidLoggedIn,
                                            object: nil,
                                            userInfo: [Link.loggedInUserIDKey : auth.userID])
        }
        sessionStore.userDidLogout = { uid in
            NotificationCenter.default.post(name: .userDidLoggedOut,
                                            object: nil,
                                            userInfo: [Link.loggedOutUserIDKey : uid])
        }
    }
}

extension Link: LinkAPI {
    @discardableResult
    public func performRegistration(_ viewController: UIViewController? = nil, completionHandler: @escaping (Result<User>) -> Void) -> UIViewController? {
        let v = viewController ?? UIApplication.shared.mainAppWindow?.rootViewController
        
        guard let parentVc = v else {
            return nil
        }
        
        let registration = RegistrationViewController.init()
        parentVc.present(registration, animated: true, completion: nil)
        
        return registration
    }
    
    
    @discardableResult
    public func performBasicAuthLogin(_ viewController: UIViewController? = nil,
                                      completionHandler: @escaping (Result<AuthSession>) -> Void) -> UIViewController? {
        assertMainThread()
        
        let v = viewController ?? UIApplication.shared.mainAppWindow?.rootViewController
        
        guard let parentVc = v else {
            return nil
        }
        
        let userAuth = LoginViewController.init()
        userAuth.completionHandler = {
            completionHandler($0)
        }
        
        parentVc.present(userAuth, animated: true, completion: nil)
        return userAuth
    }
    
    
}

#if canImport(RxSwift)
import RxSwift

extension Link: ReactiveCompatible {}

extension Reactive: RxLinkAPI where Base: Link {
    
    public func performRegistration(_ viewController: UIViewController? = nil) -> Observable<Result<User>> {
        assertMainThread()
        
        return Observable.create({ (observer) -> Disposable in
            
            let destination = self.base.performRegistration(viewController, completionHandler: {
                observer.onNext($0)
                observer.onCompleted()
            })
            
            return Disposables.create {
                destination?.dismiss(animated: true, completion: nil)
            }
        })
    }
    
    
    public func performBasicAuthLogin(_ viewController: UIViewController? = nil) -> Observable<Result<AuthSession>> {
        assertMainThread()
        return Observable.create { (observer) -> Disposable in
            let destination = self.base.performBasicAuthLogin(viewController, completionHandler: {
                
                guard $0.isSuccess else {
                    observer.onNext($0)
                    return
                }
                observer.onNext($0)
                observer.onCompleted()
            })
            return Disposables.create {
                destination?.dismiss(animated: true, completion: nil)
            }
        }
    }
}
#endif
